#include <config.h>
#include <common.h>
#include <command.h>
#include <i2c.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <linux/ctype.h>


#if defined(CONFIG_CMD_I2C)

	

void i2c_start(void)
{
	I2C_DELAY;
	I2C_SDA(1);
	I2C_DELAY;
	I2C_SCL(1);
	I2C_DELAY;
	I2C_SDA(0);
	I2C_DELAY;
}

void i2c_stop(void)
{
	I2C_SCL(0);
	I2C_DELAY;
	I2C_SDA(0);
	I2C_DELAY;
	I2C_SCL(1);
	I2C_DELAY;
	I2C_SDA(1);
}

void i2c_ack(int ack)
{
	I2C_SCL(0);
	I2C_DELAY;
	I2C_SDA(ack);
	I2C_DELAY;
	I2C_SCL(1);
	I2C_DELAY;
	I2C_SCL(0);
	I2C_DELAY;
}

u8 i2c_wait_ack(void)
{
	u8 Time = 0;
	while(I2C_READ())
	{
		Time++;
		if(Time > 250)
		{
			i2c_stop();
			return 1;
		}
		I2C_DELAY;
	}
	return 0;
}

u8 i2c_read_byte(u8 ack)
{
	int data;
	int j;

	I2C_SDA(1);
	data = 0;

	for(j = 0; j < 8;j++)
	{
		I2C_SCL(0);
		I2C_DELAY;
		I2C_SCL(1);
		I2C_DELAY;
		data <<= 1;
		data |= I2C_READ();
		I2C_DELAY;
	}
	i2c_ack(ack);

	return data;
}

u8 i2c_write_byte(u8 dat)
{
	u8 ack;
	u8 mask;

	for(mask = 0; mask < 8; mask++)
	{
		I2C_SCL(0);
		I2C_SDA(dat & 0x80);
		I2C_SCL(1);
		I2C_DELAY;
		dat <<= 1;
	}
	
	I2C_SCL(0);
	I2C_DELAY;
	ack = i2c_wait_ack();
	if(!ack)
		I2C_SCL(1);
	else
		I2C_SCL(0);

	I2C_DELAY;

	return ack;
}

u8 i2c_probe(u8 addr)
{
	u8 ack;
	
	i2c_start();
	
	ack = i2c_write_byte(addr << 1);

	i2c_stop();

	return ack;
}

/*
 * Syntax:
 * i2c probe {addr}{.0, .1, .2}
 */

static int do_i2c_probe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	u8 j;

	puts("Valid chip addresses:");
	
	for(j = 0; j < 128; j++)
	{	
		if(i2c_probe(j) == 0)
			printf(" %02x probe ok\n", j);
		
	}

	return 0;
}

static cmd_tbl_t cmd_i2c_sub[] = {
	U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""),
};

int do_i2c(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	cmd_tbl_t *c;

	if(argc < 2)
		return CMD_RET_USAGE;

	argc--;
	argv++;

	c = find_cmd_tbl(argv[0], &cmd_i2c_sub[0], ARRAY_SIZE(cmd_i2c_sub));

	if(c){
		return c->cmd(cmdtp, flag, argc, argv);
	}
	else
	{
		return CMD_RET_USAGE;	
	}
}

U_BOOT_CMD(i2c, 6, 1, do_i2c,
			"i2c sub-system\n",
			"i2c [p]robe\n"
);

#endif
